import axios from 'axios'
import type {
  AxiosInstance,
  AxiosError,
  InternalAxiosRequestConfig,
  AxiosRequestConfig,
  AxiosResponse,
} from 'axios'

import {BASE_URL,TIMEOUT} from "./config"
class HttpRequest {
  baseURL: string
  timeout: number

  /**
   * 构造函数
   * @description 初始化对象并设置基本属性
   * @constructor
   */
  constructor() {
    this.baseURL = BASE_URL
    this.timeout = TIMEOUT
  }

  /**
   * 合并选项
   * @param options 待合并的选项对象
   * @returns 合并后的选项对象，包含基础URL、超时时间和待合并的选项对象
   */
  mergeOptions(options: AxiosRequestConfig): AxiosRequestConfig {
    return { baseURL: this.baseURL, timeout: this.timeout, ...options }
  }

  /**
   * 处理状态码
   * @param status 状态码
   * @param data 响应数据
   * @returns 处理后的结果或错误信息
   */
  handleStatusCode(status: number, data: any): any {
    switch (status) {
      case 200:
        return data
      case 400:
        console.error('请求错误：', data.message)
        break
      case 401:
        console.error('未授权，请登录')
        break
      case 403:
        console.error('拒绝访问')
        break
      case 404:
        console.error('请求地址出错')
        break
      case 500:
        console.error('服务器内部错误')
        break
      default:
        console.error('未知错误')
    }
    return Promise.reject(data)
  }

  /**
   * 设置请求拦截器和响应拦截器
   * @param instance axios 实例
   * @returns 无返回值
   */
  setInterceptors(instance: AxiosInstance): void {
    // 请求拦截器
    instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 可以在这里添加 token 或其他自定义请求头
        return config
      },
      (error: AxiosError) => {
        console.error('请求错误', error)
        return Promise.reject(error)
      },
    )
    // 响应拦截器
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        return this.handleStatusCode(response.status, response.data)
      },
      (error: AxiosError) => {
        const { response } = error
        if (response) {
          return this.handleStatusCode(response.status, response.data)
        }
        console.error('网络错误', error)
        return Promise.reject(error)
      },
    )
  }

  /**
   * 创建axios实例
   * @param options 配置选项
   * @returns 返回创建的axios实例
   */
  createInstance(options: AxiosRequestConfig): AxiosInstance {
    const instance = axios.create(this.mergeOptions(options))
    this.setInterceptors(instance)
    return instance
  }

  /**
   * 发起请求
   * @param options 请求选项
   * @returns 返回请求实例
   */
  request(options: AxiosRequestConfig): Promise<AxiosResponse> {
    const instance = this.createInstance(options)
    return instance(options)
  }

  /**
   * 发起 GET 请求
   * @param url 请求的 URL 地址
   * @param config 配置参数对象，可选
   * @returns 返回 Promise 对象，表示异步请求的结果
   */
  get(url: string, config: AxiosRequestConfig = {}): Promise<AxiosResponse> {
    return this.request({ url, method: 'get', ...config })
  }

  /**
   * 发送 POST 请求
   * @param url 请求的 URL 地址
   * @param data 请求的数据
   * @param config 请求的配置项，可选参数
   * @returns 返回请求的结果
   */
  post(
    url: string,
    data?: any,
    config: AxiosRequestConfig = {},
  ): Promise<AxiosResponse> {
    const params = {
      url,
      method: 'post',
      ...config,
    }
    if (data) {
      params.data = data
    }
    return this.request(params)
  }

  /**
   * 发送文件上传请求
   * @param url 请求的 URL 地址
   * @param formData 包含上传文件的 FormData 对象
   * @param config 请求的配置项，可选参数
   * @returns 返回请求的结果
   */
  upload(
    url: string,
    formData: FormData,
    config: AxiosRequestConfig = {},
  ): Promise<AxiosResponse> {
    return this.request({
      url,
      method: 'post',
      data: formData,
      headers: { 'Content-Type': 'multipart/form-data' },
      ...config,
    })
  }
}

export default new HttpRequest()
